package com.xjk.compressor;

import com.xjk.encryp.Base64;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;

public class GzipUtil {

    /**
     * 压缩
     */
    public static String compress(String str, String charset) throws IOException {
        if (str == null || str.length() == 0) {
            return str;
        }
        ByteArrayOutputStream out = null;
        GZIPOutputStream gzip = null;
        try {
            out = new ByteArrayOutputStream();
            gzip = new GZIPOutputStream(out);
            gzip.write(str.getBytes(charset));
            gzip.flush();
            gzip.finish();
            String encode = new String(Base64.encodeBase64(out.toByteArray()));
            return encode;
        } finally {
            if (null != gzip) {
                gzip.close();
            }
            if (null != out) {
                out.close();
            }
        }
    }

    /**
     * 解压
     */
    public static String uncompress(String str, String charset) throws IOException {
        if (str == null || str.length() == 0) {
            return str;
        }
        ByteArrayOutputStream out = null;
        ByteArrayInputStream in = null;
        GZIPInputStream gzip = null;
        try {
            out = new ByteArrayOutputStream();
            in = new ByteArrayInputStream(Base64.decodeBase64(str.getBytes(charset)));
            gzip = new GZIPInputStream(in);
            byte[] buffer = new byte[256];
            int n;
            while ((n = gzip.read(buffer)) >= 0) {
                out.write(buffer, 0, n);
            }
            out.flush();
            return out.toString(charset);
        } finally {
            if (null != in) {
                in.close();
            }
            if (null != gzip) {
                gzip.close();
            }
            if (null != out) {
                out.close();
            }
        }
    }

    public static void archive2Tar(String sourceFilePath, String targetFile) throws IOException {
        File sourceFile = new File(sourceFilePath);
        if (sourceFile.exists()
                && sourceFile.isDirectory()
                && sourceFile.list().length > 0) {
            TarArchiveOutputStream taros = new TarArchiveOutputStream(new FileOutputStream(targetFile));
            for (String name : sourceFile.list()) {
                FileInputStream is = new FileInputStream(sourceFilePath + File.separator + name);
                TarArchiveEntry entry = new TarArchiveEntry(name);
                entry.setSize(is.available());
                taros.putArchiveEntry(entry);
                byte buff[] = new byte[1024];
                int length;
                while ((length = is.read(buff)) != -1) {
                    taros.write(buff, 0, length);
                }

                taros.closeArchiveEntry();
            }
            taros.flush();
            taros.close();
        }
    }

    public static void compress(String path) throws Exception {
        compress(path, true);
    }

    public static void compress(String path, boolean delete) throws IOException {
        File file = new File(path);
      if (file.exists() && file.isFile()) {
        compress(file, delete);
      }
    }

    public static void compress(File file, boolean delete) throws IOException {
        FileInputStream fis = new FileInputStream(file);
        FileOutputStream fos = new FileOutputStream(file.getPath() + ".gz");

        compress(fis, fos);

        fis.close();
        fos.flush();
        fos.close();

        if (delete) {
            file.delete();
        }
    }

    public static void compress(InputStream is, OutputStream os) throws IOException {
        GZIPOutputStream gos = new GZIPOutputStream(os);
        byte buff[] = new byte[1024];
        int length;
        while ((length = is.read(buff)) != -1) {
            gos.write(buff, 0, length);
        }

        gos.finish();
        gos.flush();
        gos.close();
    }
}
